/******************************************************************************
* Copyright (c) 2011-2013, Linagora
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Linagora - initial API and implementation
*******************************************************************************/
package com.ebmwebsourcing.petals.services.eip.designer.actions;
import org.eclipse.draw2d.FreeformLayer;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.LayerManager;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.StringUtils;
import com.ebmwebsourcing.petals.services.eip.PetalsEipPlugin;
import com.ebmwebsourcing.petals.services.eip.designer.model.EipChain;
/**
* @author Vincent Zurczak - EBM WebSourcing
*/
public class ExportDiagramAction extends Action {
private final static int BORDER_MARGIN_SIDES = 8;
private final static int BORDER_MARGIN_UPDOWN = 7;
private final GraphicalViewer graphicalViewer;
private final EipChain eipChain;
/**
* Constructor.
* @param graphicalViewer
* @param eipChain
*/
public ExportDiagramAction( GraphicalViewer graphicalViewer, EipChain eipChain ) {
this.graphicalViewer = graphicalViewer;
this.eipChain = eipChain;
setId( "com.ebmwebsourcing.petals.services.eip.contextmenu.exportdiagram" );
setText( "Export as an image" );
setToolTipText( "Export a diagram as an image" );
setDescription( "Export a diagram in an image file." );
ImageDescriptor desc = PetalsEipPlugin.getImageDescriptor( "icons/obj16/image.gif" );
setImageDescriptor( desc );
}
/*
* (non-Jsdoc)
* @see org.eclipse.jface.action.Action
* #run()
*/
@Override
public void run() {
// Determine the export location
FileDialog dlg = new FileDialog( new Shell(), SWT.SAVE );
dlg.setText( "Image Export" );
dlg.setOverwrite( true );
dlg.setFilterNames( new String[] { "JPEG Files (*.jpg)", "PNG Files (*.png)", "GIF Files (*.gif)" });
String[] extensions = new String[] { "*.jpg", "*.png", "*.gif" };
dlg.setFilterExtensions( extensions );
String path = dlg.open();
if( path != null ) {
String ext = extensions[ dlg.getFilterIndex()].substring( 1 );
if( ! path.endsWith( ext ))
path += ext;
// Only print printable layers
ScalableFreeformRootEditPart rootEditPart = (ScalableFreeformRootEditPart) this.graphicalViewer.getEditPartRegistry().get( LayerManager.ID );
IFigure rootFigure = ((LayerManager) rootEditPart).getLayer( LayerConstants.PRINTABLE_LAYERS );
IFigure eipChainFigure = null;
for( Object o : rootFigure.getChildren()) {
if( o instanceof FreeformLayer )
eipChainFigure = (FreeformLayer) o;
}
Rectangle bounds = eipChainFigure == null ? rootFigure.getBounds() : eipChainFigure.getBounds();
GC figureCanvasGC = new GC( this.graphicalViewer.getControl());
// Add 20 pixels to write the title of the diagram on the image
Image img = new Image( null, bounds.width, bounds.height );
GC gc = new GC( img );
gc.setBackground( figureCanvasGC.getBackground());
gc.setForeground( figureCanvasGC.getForeground());
gc.setFont( figureCanvasGC.getFont());
gc.setLineStyle( figureCanvasGC.getLineStyle());
gc.setLineWidth( figureCanvasGC.getLineWidth());
Graphics imgGraphics = new SWTGraphics( gc );
// Paint it...
rootFigure.paint( imgGraphics );
// Prepare the next step
Font font = new Font( Display.getCurrent(), "Arial", 14, SWT.BOLD );
gc.setFont( font );
int height = Dialog.convertHeightInCharsToPixels( gc.getFontMetrics(), 1 );
gc.dispose();
// Create a second image with the title and diagram version
bounds.height += height + (height%2 == 0 ? 6 : 7); // Write the title and its border
bounds.height += 3 * BORDER_MARGIN_UPDOWN + 2; // Add a border + some margin
bounds.width += 2 * BORDER_MARGIN_SIDES + 2; // Add a border
Image finalImg = new Image( null, bounds.width, bounds.height );
gc = new GC( finalImg );
// Draw a surrounding border
gc.setAntialias( SWT.ON );
gc.setForeground( Display.getCurrent().getSystemColor( SWT.COLOR_WIDGET_DARK_SHADOW ));
gc.drawLine( BORDER_MARGIN_SIDES, BORDER_MARGIN_UPDOWN, BORDER_MARGIN_SIDES, bounds.height - BORDER_MARGIN_UPDOWN );
gc.drawLine( BORDER_MARGIN_SIDES, bounds.height - BORDER_MARGIN_UPDOWN, bounds.width - BORDER_MARGIN_SIDES, bounds.height - BORDER_MARGIN_UPDOWN );
gc.drawLine( BORDER_MARGIN_SIDES, BORDER_MARGIN_UPDOWN, bounds.width - BORDER_MARGIN_SIDES, BORDER_MARGIN_UPDOWN );
gc.drawLine( bounds.width - BORDER_MARGIN_SIDES, BORDER_MARGIN_UPDOWN, bounds.width - BORDER_MARGIN_SIDES, bounds.height - BORDER_MARGIN_UPDOWN );
// Draw the title
gc.setForeground( Display.getCurrent().getSystemColor( SWT.COLOR_BLACK ));
gc.setFont( font );
gc.setClipping((Region) null);
gc.setForeground( Display.getCurrent().getSystemColor( SWT.COLOR_BLACK ));
String title = this.eipChain.getTitle() != null ? this.eipChain.getTitle() : "No diagram title";
if( ! StringUtils.isEmpty( this.eipChain.getVersion()))
title += " - Version " + this.eipChain.getVersion().trim();
int width = Dialog.convertWidthInCharsToPixels( gc.getFontMetrics(), title.length());
if( width > bounds.width ) {
title = Dialog.shortenText( title, this.graphicalViewer.getControl());
width = Dialog.convertWidthInCharsToPixels( gc.getFontMetrics(), title.length());
}
gc.drawText( title, 6 + BORDER_MARGIN_SIDES, 4 + BORDER_MARGIN_UPDOWN, true );
// Draw a surrounding shape for the title
gc.setForeground( Display.getCurrent().getSystemColor( SWT.COLOR_WIDGET_DARK_SHADOW ));
Rectangle titleRectangle = new Rectangle(
BORDER_MARGIN_SIDES,
BORDER_MARGIN_UPDOWN,
BORDER_MARGIN_SIDES + width + (width%2 == 0 ? 10 : 11),
BORDER_MARGIN_UPDOWN + height + (height%2 == 0 ? 6 : 7));
final int arrowPadding = (titleRectangle.height + bounds.y) / 2;
gc.drawLine(
titleRectangle.x,
titleRectangle.height,
titleRectangle.width,
titleRectangle.height );
gc.drawLine(
titleRectangle.width,
titleRectangle.y,
titleRectangle.width + arrowPadding,
arrowPadding );
gc.drawLine(
titleRectangle.width,
titleRectangle.height,
titleRectangle.width + arrowPadding,
arrowPadding );
// Draw the image
gc.drawImage( img, BORDER_MARGIN_SIDES + 1, BORDER_MARGIN_UPDOWN + titleRectangle.height + 1 );
// Save the second image
ImageData[] imgData = new ImageData[ 1 ];
imgData[ 0 ] = finalImg.getImageData();
int format;
String tail = path.toLowerCase().substring( path.length() - 4 );
if( tail.endsWith( ".jpg" ))
format = SWT.IMAGE_JPEG;
else if( tail.endsWith( ".png" ))
format = SWT.IMAGE_PNG;
else
format = SWT.IMAGE_GIF;
ImageLoader imgLoader = new ImageLoader();
imgLoader.data = imgData;
imgLoader.save( path, format );
// Dispose everything
figureCanvasGC.dispose();
gc.dispose();
img.dispose();
finalImg.dispose();
font.dispose();
}
}
}